﻿//Faculty of Computer Science and Engineering
//Ho Chi Minh City University of Technology
//Initial code for Assignment 3 - Programming Fundamentals 501127 - Spring 2009
//Author: Nguyen Ho Man Rang
#ifndef _definition_h_
#include "defs.h"
#define _definition_h_
#endif

#define DArtagnanRelax 200 
#define AthodRelax     150 
#define PorthodRelax   100 
#define AramitRelax    50 

int i=0, j=0, k=0;
int Y; // Mã ngự lâm quân ra đánh thay b
int nE = 0;
bool useTogether = false;
bool artagnanrelax = false;
bool athodrelax = false;
bool porthodrelax = false;
bool aramitrelax = false;
bool biTeLiet = false;
bool aramitTimThayPC1ChuyenDoi = false;
bool aramitTimThayPC2ChuyenDoi = false;
bool aramitTimThayPC3ChuyenDoi = false;
int  findMusketeers[] = {0,1,2,3,0,1,2,3};

//write a function to find a primary number less than and nearest eventCode
int nearestFriLessEvent(int x){
	bool nguyento = true;
	int i = x;
	for(i=x-1; i>=1; i--){
		nguyento = true;
		if(i==1 || i==2 || i==3)
			return i;
		for(int j=2;j<i/2;j++){
			if(i%j == 0){
				nguyento = false;
				break;
			}
		}
		if(nguyento)
			return i;
	}
	return 0;
}

//  Trường hợp ARAMIT ra đấu. 
// Viết hàm tìm số > XY mà chia hết cho 3
int soLonHonXYChiaHet3(int XY){
	for(int i = 0; i<3; i++){
		if((XY+i)%3==0){
			return XY+i;
		}
	}
}
int damange(int eventXY, float fE, int I, int Ei){
	int k = nearestFriLessEvent(Ei);
	return (int)(pow(eventXY, fE)) + (int)(pow(fE,(I+1))*nearestFriLessEvent(Ei))%100;
}

//initialize the originally values of the musketeers
void init(int D[], int A[], int P[], int R[], musketeer M[]) {
	//TODO
	M[0].HP = 999;
	if(D[0]<=0){ M[0].pC1 = NULL; M[0].npC1 = 0; }
	else{ newCrystal(M[0].pC1, 0, D[0]); M[0].npC1 = 1;}
	if(D[1]<=0){ M[0].pC2 = NULL; M[0].npC2 = 0; }
	else{ newCrystal(M[0].pC2, 0, D[1]); M[0].npC2 = 1;}
	if(D[2]<=0){ M[0].pC3 = NULL; M[0].npC3 = 0; }
	else{ newCrystal(M[0].pC3, 0, D[2]); M[0].npC3 = 1;}

	M[1].HP = 900;
	if(A[0]<=0){ M[1].pC1 = NULL; M[1].npC1 = 0; }
	else{ newCrystal(M[1].pC1, 0, A[0]); M[1].npC1 = 1;}
	if(A[1]<=0){ M[1].pC2 = NULL; M[1].npC2 = 0; }
	else{ newCrystal(M[1].pC2, 0, A[1]); M[1].npC2 = 1;}
	if(A[2]<=0){ M[1].pC3 = NULL; M[1].npC3 = 0; }
	else{ newCrystal(M[1].pC3, 0, A[2]); M[1].npC3 = 1;}

	M[2].HP = 888;
	if(P[0]<=0){ M[2].pC1 = NULL; M[2].npC1 = 0; }
	else{ newCrystal(M[2].pC1, 0, P[0]); M[2].npC1 = 1;}
	if(P[1]<=0){ M[2].pC2 = NULL; M[2].npC2 = 0; }
	else{ newCrystal(M[2].pC2, 0, P[1]); M[2].npC2 = 1;}
	if(P[2]<=0){ M[2].pC3 = NULL; M[2].npC3 = 0; }
	else{ newCrystal(M[2].pC3, 0, P[2]); M[2].npC3 = 1;}

	M[3].HP = 777;
	if(R[0]<=0){ M[3].pC1 = NULL; M[3].npC1 = 0; }
	else{ newCrystal(M[3].pC1, 0, R[0]); M[3].npC1 = 1;}
	if(R[1]<=0){ M[3].pC2 = NULL; M[3].npC2 = 0; }
	else{ newCrystal(M[3].pC2, 0, R[1]); M[3].npC2 = 1;}
	if(R[2]<=0){ M[3].pC3 = NULL; M[3].npC3 = 0; }
	else{ newCrystal(M[3].pC3, 0, R[2]); M[3].npC3 = 1;}

}


int battle(musketeer M[], int I, int E[], int nEvent) {	
	//TODO
	nE = 0;
	float fE =0;
	while(nEvent >0){
		aramitTimThayPC1ChuyenDoi = false;
		aramitTimThayPC2ChuyenDoi = false;
		aramitTimThayPC3ChuyenDoi = false;
		int eventID = E[nE]/100;
		int eventXY = E[nE]%100;
		if(eventID==4)			fE = QUEZACOLT;
		else if(eventID ==5)	fE = BAHAMUT;
		else if(eventID ==6)	fE = CERBERUS;
		else if(eventID ==7)	fE = IFRIT;
		else if(eventID ==8)	fE = SIREN;
		else					fE = LEVIATHAN;

		switch(eventID){
		case 1:
			newCrystal(M[I].pC1, M[I].npC1, eventXY);
			M[I].npC1++;
			break;
		
		case 2:
			newCrystal(M[I].pC2, M[I].npC2, eventXY);
			M[I].npC2++;
			break;
		
		case 3:
			newCrystal(M[I].pC3, M[I].npC3, eventXY);
			M[I].npC3++;
			break;
		case 4:
		case 5:
			while(M[I].pC1)
			{
				if(M[I].pC1->level > eventXY)
				{
					M[I].pC1->level -= eventXY;
					break;
				}
				else
				{
					Crystal* tempC1 = M[I].pC1;												
					eventXY -= M[I].pC1->level;
					M[I].pC1 = M[I].pC1->nextCrystal;
					deleteCrystal(tempC1);
				}
			}// Tìm ngu lam quan khac có PC1 để dùng chung
			if(!M[I].pC1)
			{
				for(i=0; i<4; i++)
					if(i==I) break;
				for(j=i+1; j<i+4; j++)
				{
					eventXY +=3;
					if(M[findMusketeers[j]].pC1)
					{
						useTogether = true;
						break;// da tim thay ngu lam quan co cung loai crystal.
					}
				}
				if(useTogether)
				{
					k = findMusketeers[j];	// tồn tại 1 musketeer khác có pC1
					while(M[k].pC1)
					{
						if(M[k].pC1->level > eventXY)
						{
							M[k].pC1->level -= eventXY;
							break;
						}
						else
						{
							Crystal* tempC1 = M[k].pC1;												
							eventXY -= M[k].pC1->level;
							M[k].pC1 = M[k].pC1->nextCrystal;
							deleteCrystal(tempC1);		
						}
					}
				}
				else         
				{
					if(I==3 && M[3].HP > soLonHonXYChiaHet3(eventXY))   // aramit, gỉa kim thuật
					{
						for(i=3; i<=6; i++)
						{// lần lượt tìm ngự lâm quân có hạt Crystal thỏa điều kiện
							k = findMusketeers[i];
							Crystal* tempC2 = M[k].pC2;
							Crystal* preTempC2 = M[k].pC2;
							Crystal* tempC3 = M[k].pC3;
							Crystal* preTempC3 = M[k].pC3;
							while(tempC2)
							{
								if(tempC2->level > eventXY){
									aramitTimThayPC2ChuyenDoi = true;
									newCrystal(M[3].pC1, 0, tempC2->level - 1);
									M[3].pC1->level -= eventXY; 
									if(M[3].pC1->level <=0 ) {
										Crystal* newChangePC1 = M[3].pC1;
										deleteCrystal(newChangePC1);
									}  
									// Cần xóa viên pC2, mà armit đã dùng để chuyển đổi
									if(tempC2=M[k].pC2){
										M[k].pC2 = M[k].pC2->nextCrystal;
										Crystal* te = tempC2;
										deleteCrystal(te);
									}
									else{
										preTempC2->nextCrystal = tempC2->nextCrystal;
										deleteCrystal(tempC2);
										tempC2=preTempC2;
									}
									
									break;
								}
								preTempC2 = tempC2;
								tempC2 = tempC2->nextCrystal;
							}
							// Nếu ko tìm thấy pC2 nào thỏa mãn. tiếp đến là tìm pC3
							if(!aramitTimThayPC2ChuyenDoi){
								while(tempC3){
									if(tempC3->level > eventXY)
									{
										aramitTimThayPC3ChuyenDoi = true;
										newCrystal(M[3].pC1, 0, tempC2->level - 1);
										M[3].pC1->level -= eventXY;
										if(M[3].pC1->level == 0) deleteCrystal(M[3].pC1);
										break;
									}
									tempC3 = tempC3->nextCrystal;									
								}
							}
						}
					}
					else{
						M[I].HP -= damange(eventXY,fE,I,E[nE]);
						if(M[I].HP>0){
							if(M[I].HP <= 0){
								M[I].HP = 0;
								if(I==0)
									artagnanrelax = true; // Nhờ bạn ra đánh thay
								if(I==1)
									athodrelax = true;
								if(I==2)
									porthodrelax = true;
								if(I==3)
									aramitrelax = true;
							}
						}					
					}
				}//end case, not use together.
			}// end case , the musketeer haven't Crystal.
			break;
		}
		if(artagnanrelax == true || athodrelax == true || porthodrelax == true){
			I +=1;
		}
		if( aramitrelax == true )
			I = 0;
	nE++;
		nEvent--;		
			if(artagnanrelax == true && I!=0 ) M[Y].HP += DArtagnanRelax;	if(I==0) artagnanrelax = false;
			if(athodrelax == true && I!=1) M[Y].HP += AthodRelax;			if(I==1) athodrelax = false;
			if(porthodrelax == true && I!=2) M[Y].HP += PorthodRelax;		if(I==2) porthodrelax = false;
			if(aramitrelax == true && I!=3) M[Y].HP += AramitRelax;			if(I==3) aramitrelax = false;
		
	}
	return 0;

}
